package cn.com.libertymutual.core.common.util;

import java.lang.reflect.Method;
import java.util.Properties;

import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.PropertyResourceConfigurer;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.io.support.PropertiesLoaderSupport;

public class ApplicationContextUtil {
	private static Properties prop = new Properties();
	private static AbstractApplicationContext applicationContext;
	
	private static ApplicationContextUtil instance = null;
	
	protected ApplicationContextUtil() {
	}
	
	public static ApplicationContextUtil getInstance() {
		return instance == null ? new ApplicationContextUtil() : instance;
	}
	
	public static AbstractApplicationContext getAbstractApplicationContext() {
		return applicationContext;
	}
	
	public void init( AbstractApplicationContext applicationContext ) throws Exception {
		///AbstractApplicationContext aac =  (AbstractApplicationContext) WebApplicationContextUtils.getWebApplicationContext(sc);
		///applicationContext = aac;
		this.applicationContext = applicationContext;
		
		String ps[] = applicationContext.getBeanNamesForType(BeanFactoryPostProcessor.class, true, true);
		for (String string : ps) {
			BeanFactoryPostProcessor bp = applicationContext.getBean(string, BeanFactoryPostProcessor.class);
			if( bp instanceof PropertyResourceConfigurer ) {
				PropertyResourceConfigurer prc = (PropertyResourceConfigurer) bp;
				Method m = PropertiesLoaderSupport.class.getDeclaredMethod("mergeProperties");
				m.setAccessible(true);
				Properties props = (Properties) m.invoke(prc);
				Method cm = PropertyResourceConfigurer.class.getDeclaredMethod("convertProperties", Properties.class);
				cm.setAccessible(true);
				cm.invoke(prc, props);
				prop.putAll( props );
			}
		}
	}
	
	public String getProperty( String propertyName ) {
		return prop.getProperty( propertyName );
	}
	
	public String getProperty( String key, String defaultValue ) {
		return prop.getProperty(key, defaultValue);
	}
	
	public Object get(Object key) {
		return prop.get(key);
	}
	

	public static <T> T getBean( String beanName, Class<T> clazz  ) {
		return applicationContext.getBean(beanName, clazz);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T getBean( String beanName ) {
		return (T) applicationContext.getBean(beanName);
	}
}
